package com.ww.java8.fp.stream;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CreatingStreams {

	public static <T> void show(String title, Stream<T> stream) {
		final int SIZE = 10;
		List<T> firstElements = stream.limit(SIZE + 1).collect(Collectors.toList());
		System.out.print(title + ":");
		for (int i = 0; i < firstElements.size(); i++) {
			if (i > 0) {
				System.out.print(", ");
			}
			if (i < SIZE) {
				System.out.print(firstElements.get(i));
			} else {
				System.out.print("...");
			}
		}
		System.out.println();
	}
	
	public static void main(String[] args) throws IOException {
		Path path = Paths.get("D:/test/test.txt");
		String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
		
		// 以非字母分隔符
		Stream<String> words = Stream.of(contents.split("\\PL+"));
		show("words", words);
		
		// 使用数组创建流
		Stream<String> song = Stream.of("gently", "down", "the", "stream");
		show("song", song);
		
		// 创建空流
		Stream<String> silence = Stream.empty();
		show("silence", silence);
		
		// generate，lambda表达式创建流，无限流
		// 输出结果
		// echos:Echo, Echo, Echo, Echo, Echo, Echo, Echo, Echo, Echo, Echo, ...
		Stream<String> echos = Stream.generate(() -> "Echo");
		show("echos", echos);
		
		// generate，随机数创建流，无限流
		// 输出结果
		// randoms:0.4485350717469089, 0.46602892749889213, 0.5350040620189707, 0.15504607298744044, 0.3952619785604937, 0.5653682964308608, 0.6714137930160136, 0.6708447684223621, 0.21924934057592405, 0.07426856363482381, ...
		Stream<Double> randoms = Stream.generate(Math::random);
		show("randoms", randoms);
		
		// 累加，无限流
		// 它的值是通过反复调用函数s而构建
		// 输出结果
		// integers:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
		Stream<BigInteger> integers = Stream.iterate(BigInteger.ONE, n -> n.add(BigInteger.ONE));
		show("integers", integers);
		
		// 正则表达式拆分
		Stream<String> wordsAnotherWay = Pattern.compile("\\PL+").splitAsStream(contents);
		show("wordsAnthorWay", wordsAnotherWay);
		
		// 使用Files.lines
		try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {
			show("lines", lines);
		}
	}
}
